package id.mankel.commons.security.shiro;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.springframework.context.annotation.Bean;

import javax.servlet.Filter;
import java.util.List;
import java.util.Map;

/**
 * @author Mankel
 */
//@Configuration
public class ShiroConfig {

    private static final String SHIRO_ACTIVE_SESSIONS = "SHIRO_ACTIVE_SESSIONS";

    @Bean
    SessionDAO sessionDAO() {
        EnterpriseCacheSessionDAO sessionDAO = new EnterpriseCacheSessionDAO();
        sessionDAO.setActiveSessionsCacheName(SHIRO_ACTIVE_SESSIONS);
        return sessionDAO;
    }

    @Bean
    CacheManager cacheManager() {
        return new RedisCacheManager();
    }

    @Bean
    Realm realm() {
        return new ShiroRealm(new HashedCredentialsMatcher(Sha256Hash.ALGORITHM_NAME));
    }

    @Bean
    ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager, List<String> globalFilters) {
        ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();

//        filterFactoryBean.setLoginUrl(WebConfig.getPath("/sys/unauthenticated"));
//        filterFactoryBean.setSuccessUrl(successUrl);
//        filterFactoryBean.setUnauthorizedUrl(unauthorizedUrl);

        filterFactoryBean.setSecurityManager(securityManager);
        filterFactoryBean.setGlobalFilters(globalFilters);




        // custom filter(s)
        Map<String, Filter> filterMap = filterFactoryBean.getFilters();
        filterMap.put("custom", new CustomFilter());
        filterMap.put("authc", new AuthcFilter());

        Map<String, String> filterChainDefinitionMap = filterFactoryBean.getFilterChainDefinitionMap();
//        Streams.concat(Stream.of(
//                "/actuator/**",
//                "/favicon.ico",
//                "/error"
//        ), Stream.of(
//                "/sys/signIn",
//                "/sys/signOut",
//                "/sys/hasSignedIn",
//                "/test/**"
//        ).map(WebConfig::getPath)).forEachOrdered(path -> filterChainDefinitionMap.put(path, "anon"));
        filterChainDefinitionMap.put("/custom/**", "custom"); // using custom filter
//        filterChainDefinitionMap.put("/**", "anon");
        filterChainDefinitionMap.put("/**", "authc");





//        filterFactoryBean.setFilterChainDefinitionMap(shiroFilterChainDefinition.getFilterChainMap());
//        filterFactoryBean.setFilters(filterMap);

        return filterFactoryBean;
    }

}
